chore: visual updates#174
Conversation
WalkthroughUI-focused updates across Telegram app: configuration tweak to Drawer ring class; ActiveCard component gains optional class prop; styling/layout adjustments in message components; ticket pages reorganized (new edit handler; Drawer content restructured; list gains header); minor style changes on tasks page and image press effect. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant TicketPage as Ticket Detail Page
participant Haptics as vibrate()
User->>TicketPage: Click pencil (Edit)
activate TicketPage
TicketPage->>Haptics: handleEdit()
deactivate TicketPage
note right of Haptics: Triggers haptic feedback
sequenceDiagram
autonumber
actor User
participant Drawer as Drawer (Ticket Detail)
participant Form as FormCreateTicketMessage
User->>Drawer: Click "Написать сообщение" (default slot button)
note right of Drawer: Default slot button present in Drawer header area
Drawer->>Form: Show body with FormCreateTicketMessage
User->>Form: Submit / interact (unchanged bindings)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/atrium-telegram/app/pages/ticket/[ticketId]/index.vue (1)
98-102: Bug: shows first N messages, not the last N as comment states.Use negative slice to take from the end.
Apply:
-const messages = computed(() => ticket.value?.messages.slice(0, shownMessages.value)) +const messages = computed(() => ticket.value?.messages.slice(-shownMessages.value))
🧹 Nitpick comments (8)
apps/atrium-telegram/app/pages/tasks/index.vue (2)
6-8: Avatar remains clickable but lost affordance; add pointer and ARIA.Without
cursor-pointer, the tap target looks inert. Also add an accessible name since it triggers an action.Apply:
- class="size-14 border-2 border-primary hover:scale-95 active:scale-90 duration-200" + class="size-14 border-2 border-primary hover:scale-95 active:scale-90 duration-200 cursor-pointer" + role="button" + aria-label="Изменить аватар"
17-24: ULink rendered as button: confirm pointer cursor.
as="button"may not get a pointer cursor depending on resets. If not, addcursor-pointerto keep affordance.apps/atrium-telegram/app/components/ticket/MessageImage.vue (1)
3-7: Add lazy-loading and meaningful alt text.Improves performance and a11y for content images.
Apply:
- <img + <img :src="message.fileUrl" - alt="" - class="w-full h-full object-contain rounded-lg active:scale-95 duration-200" + alt="Изображение" + loading="lazy" + decoding="async" + class="w-full h-full object-contain rounded-lg active:scale-95 duration-200" >apps/atrium-telegram/app/components/ticket/MessageText.vue (1)
2-2: Likely width mix-up: use max-w, not min-w.
!w-fit min-w-2/3forces bubbles to be at least 2/3 width. Chats usually cap max width.Apply:
- <ActiveCard class="!w-fit min-w-2/3"> + <ActiveCard class="!w-fit max-w-2/3">apps/atrium-telegram/app/components/ActiveCard.vue (1)
2-3: Explicittype="button"to avoid accidental form submits.Safe default when this button appears inside forms.
Apply (already included in diff above).
apps/atrium-telegram/app/pages/ticket/index.vue (1)
4-6: Consider i18n for the new header.Wrap in
$t(...)to keep localization consistent across the app.Example:
- <div class="text-2xl/6 font-bold tracking-tight"> - Активные тикеты - </div> + <div class="text-2xl/6 font-bold tracking-tight" v-text="$t('ticket.active-tickets')" />apps/atrium-telegram/app/components/ticket/MessageFile.vue (1)
48-51: Typo in Russian: “файл” uses a combining mark; use “файл”.Prevents search/matching issues.
Apply:
- label: 'Загружен файл', + label: 'Загружен файл',apps/atrium-telegram/app/pages/ticket/[ticketId]/index.vue (1)
7-13: Icon-only button needs an accessible name.Add
aria-label(and optionaltitle) for screen readers.Apply:
<UButton variant="soft" color="primary" size="xl" icon="i-lucide-pencil" + aria-label="Редактировать" + title="Редактировать" @click="handleEdit()" />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/atrium-telegram/app/app.config.ts(1 hunks)apps/atrium-telegram/app/components/ActiveCard.vue(1 hunks)apps/atrium-telegram/app/components/ticket/MessageFile.vue(2 hunks)apps/atrium-telegram/app/components/ticket/MessageImage.vue(1 hunks)apps/atrium-telegram/app/components/ticket/MessageText.vue(1 hunks)apps/atrium-telegram/app/pages/tasks/index.vue(2 hunks)apps/atrium-telegram/app/pages/ticket/[ticketId]/index.vue(4 hunks)apps/atrium-telegram/app/pages/ticket/index.vue(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
apps/atrium-telegram/app/app.config.ts (1)
63-64: Verifyring-default/50compiles — confirmdefaultis a Tailwind color token.I couldn't find any tailwind.config.* in the repo to confirm a theme color named
default(packages/ui/app/app.config.ts defines colors but notdefault). Occurrences to check: apps/atrium-telegram/app/app.config.ts:63 (content: '!max-h-10/12 ring-default/50 hide-scroll') and apps/web-app/app/components/ActiveCard.vue:3 (class includes 'ring-default/50'). Ifdefaultis not a theme color, the/50will be dropped — either define theme.colors.default, remove the/50, or use an explicit opacity approach (e.g., ring-default + ring-opacity-50 or an arbitrary color with/50).
| <button | ||
| class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" | ||
| :class="props.class" | ||
| @click="vibrate()" | ||
| > |
There was a problem hiding this comment.
Don’t declare class as a prop; rely on Vue’s native class merging.
class is special in Vue and auto‑merges to the root; declaring it as a prop is unnecessary and can cause surprises. Drop the prop and binding.
Apply:
- <button
- class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0"
- :class="props.class"
- @click="vibrate()"
- >
+ <button
+ class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0"
+ type="button"
+ @click="vibrate()"
+ >And:
-const props = defineProps<{ class?: string }>()
-
const { vibrate } = useFeedback()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button | |
| class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" | |
| :class="props.class" | |
| @click="vibrate()" | |
| > | |
| const { vibrate } = useFeedback() | |
| <button | |
| class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" | |
| type="button" | |
| @click="vibrate()" | |
| > |
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/ActiveCard.vue around lines 2–6, the
template declares and binds a `class` prop (":class=\"props.class\"") which is
unnecessary because Vue automatically merges classes on the root element; remove
the `class` prop declaration from the component props and delete the
`:class="props.class"` binding in the template so parent classes merge natively;
if the component needs to forward other attributes, ensure it uses
v-bind="$attrs" (or enable inheritAttrs) so other attributes still pass through.
| <ActiveCard> | ||
| <div class="w-full relative flex flex-col justify-between gap-2"> | ||
| <div class="p-2 w-16 h-10 flex flex-row items-center justify-center bg-primary rounded-md"> | ||
| <UIcon :name="getFileData(message.fileType).icon" class="size-6 tg-text-button" /> | ||
| </div> | ||
|
|
||
| <UButton | ||
| variant="soft" | ||
| color="secondary" | ||
| :label="getFileData(message.fileType).label" | ||
| /> | ||
| </div> | ||
| <div v-if="message?.createdAt" class="flex justify-end text-xs text-muted"> | ||
| {{ format(new Date(message.createdAt), 'dd MMMM в HH:mm', { locale: ru }) }} | ||
| </div> | ||
| <div class="text-base/5 whitespace-break-spaces text-default font-medium"> | ||
| {{ getFileData(message.fileType).label }} | ||
| </div> | ||
|
|
||
| <div v-if="message?.createdAt" class="flex justify-end text-xs text-muted"> | ||
| {{ format(new Date(message.createdAt), 'dd MMMM в HH:mm', { locale: ru }) }} | ||
| </div> | ||
| </div> | ||
| </ActiveCard> |
There was a problem hiding this comment.
No way to open/download the attachment after removing the button.
Add a click handler (or link) to open message.fileUrl; keep vibrate via ActiveCard.
Apply:
- <ActiveCard>
+ <ActiveCard
+ @click="handleOpenAttachment"
+ :aria-label="getFileData(message.fileType).label"
+ >Add handler:
]>()
function getFileData(type: TicketMessage['fileType']) {
switch (type) {
@@
}
}
+
+function handleOpenAttachment() {
+ if (message?.fileUrl) {
+ window.open(message.fileUrl, '_blank', 'noopener,noreferrer')
+ }
+}🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/ticket/MessageFile.vue around lines 3-17,
the attachment UI no longer offers any way to open or download the file after
the button was removed; add an interactive handler on the card (or wrap the file
area in an anchor) that opens message.fileUrl. Implement by wiring a click
handler on the ActiveCard container (or using an <a> with target="_blank"
rel="noopener noreferrer" and download when appropriate) that opens
message.fileUrl in a new tab; keep the existing ActiveCard vibrate behavior and
ensure the click is accessible (cursor pointer, aria-label) and guards against
missing URL before opening.



Summary by CodeRabbit
New Features
Style